#include "scene.h"


void scene::setCameraPosition(const glm::vec2 &camera_position_)
{
    camera_position = camera_position_;
    camera_position = glm::clamp(camera_position, glm::vec2(-30),
         world_size - game_.getScreenSize() + glm::vec2(30));
}

void scene::addChild(node* child)
{
    switch (child->getType())
    {
    case NODE_SCREEN:
        //SDL_Log("addChild SCREEN name:%s",child->name_.c_str());
        children_screen_.push_back(dynamic_cast<screen*>(child));
        break;
    case NODE_WORLD:
    case ENEMY: 
        //SDL_Log("addChild WORLD name:%s",child->name_.c_str());
        children_world_.push_back(dynamic_cast<world*>(child));
        break;
    default:
        //SDL_Log("addChild children_ name:%s",child->name_.c_str());
        children_.push_back(child);
        break;
    }

}

void scene::removeChild(node*  child){
    SDL_Log("removeChild children_ name:%s",child->name_.c_str());
    switch(child->getType())
    {
    case NODE_SCREEN:
        children_screen_.erase(std::remove(children_screen_.begin(), children_screen_.end(), dynamic_cast<screen*>(child)), children_screen_.end());
        break;
    case NODE_WORLD:
    case ENEMY:
        children_world_.erase(std::remove(children_world_.begin(), children_world_.end(), dynamic_cast<world*>(child)), children_world_.end());
        break;
    default:
        children_.erase(std::remove(children_.begin(), children_.end(), child), children_.end());
        break;
    }
}

void scene::looplog(node* child)
{
    if(child == nullptr) return;
    SDL_Log("looplog:%s active:%d",child->name_.c_str(),child->isActive());
    for(auto& c : child->getChildren()){
        looplog(c);
    }
        //SDL_Log("children_world_.size:%d",children_world_.size());
}

void scene::init()
{
    node::init();
}

void scene::update(float dt)
{
    if(!isPause){
        node::update(dt);
        for (auto it = children_world_.begin(); it != children_world_.end();)
        {
            auto child = *it;
            //SDL_Log("update WORLD name:%s",child->name_.c_str());
            if(child->getNeedRemove()){
                it = children_world_.erase(it);
                child->clean();
            }else{
                if(child->isActive()){
                    child->update(dt);
                }
                ++it;
            }
        }
    }
    for(auto it = children_screen_.begin(); it != children_screen_.end();)
    {
        auto child = *it;
        //SDL_Log("update SCREEN name:%s",child->name_.c_str());
        if(child->getNeedRemove()){
            it = children_screen_.erase(it);
            child->clean();
        }else{
            if(child->isActive()){
                child->update(dt);
            }
            ++it;
        }
    }
}

void scene::render(){
    node::render();
    for (auto& child : children_world_){
        if(child->isActive()){
            child->render();
        }
    }
    for(auto& child : children_screen_){
        if(child->isActive()){
            child->render();
        }
    }
}

bool scene::handleEvents(SDL_Event &event)
{
    for (auto& child : children_screen_){
        if(child->isActive()){
            if(child->handleEvents(event))
                return true;
        }
    }
    if(isPause) return false;
    node::handleEvents(event);
    for (auto& child : children_world_){
        if(child->isActive()){
            if(child->handleEvents(event))
                return true;
        }
    }
    return false;
}

void scene::clean(){
    node::clean();
    for(auto& child:children_screen_){
        child->clean();
        delete child;
        child = nullptr;
    }
    children_screen_.clear();
    for(auto& child:children_world_){
        child->clean();
        delete child;
        child = nullptr;
    }
    children_world_.clear();
}